﻿using App.Common;
using QxFramework.Utilities;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Maps : MonoSingleton<Maps>
{
     public   List<hexagon> cells;
    public List<GameObject> maps;

    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void LoadLevel(LevelMap nowLevel)
    {
        if (Data.Instance.inStartUI)
        {
            return;
        }
        cells = new List<hexagon>();
        /*string path = "Prefabs/Levels/Level" + Data.Instance.nowLevel + "/GMap" + Data.Instance.nowLevel;
        

        levelTr.gameObject.SetActive(true);
        //Instantiate(levelTr.gameObject);
        levelTr.position = new Vector3(0, 0, 0);
         //Transform levelTr = maps[Data.Instance.nowLevel - 1].transform;
        levelTr.gameObject.SetActive(true);*/
        Transform levelTr = nowLevel.gameObject.transform;

        for (int i = 0; i < levelTr.childCount; i++)
        {
            cells.Add(levelTr.GetChild(i).GetComponent<hexagon>());
        }
       // GetComponent<LightCheck>().Init();
    }

    public void TurnClock(List<Vector3> vectors)
    {
        foreach(var i in vectors)
        {
            hexagon t = FindHex(i);
            float k = 1;
            if (t.transform.rotation.eulerAngles.y == 180)
            {
                k = -1;
               
            }
          
            t.ClockWise();
            Vector3 v = t.transform.localEulerAngles;
            v.z = v.z-60f*k;
            t.transform.localEulerAngles = v;
        }
        
    }

    public void AntiTurnClock(List<Vector3> vectors)
    {
        foreach (var i in vectors)
        {
            hexagon t = FindHex(i);
            float k = 1;
            if (t.transform.rotation.eulerAngles.y == 180)
            {
                k = -1;
                
            }
            
            t.AntiClockWise();
            Vector3 v = t.transform.localEulerAngles;
            v.z = v.z + 60f * k;
            t.transform.localEulerAngles = v;

        }
    }


    private hexagon FindHex(Vector3 pos)
    {
        hexagon hexagon = null;
        foreach(var i in cells)
        {
            if (i.Pos == pos)
            {
                
                return i;
            }
        }
        Debug.Log("没有找到对应坐标");
        return hexagon;

    }

    public void ExchangeTwoHex(Vector3 a ,Vector3 b)
    {
        hexagon ahex = FindHex(a);
        hexagon bhex = FindHex(b);
        ExChangeAnim(ahex, bhex);//交换动画
        Vector3 temp = ahex.transform.position;
        ahex.transform.position = bhex.transform.position;
        bhex.transform.position=temp;
        temp = ahex.Pos;
        ahex.Pos = bhex.Pos;
        bhex.Pos = temp;
        
    }

    private void ExChangeAnim(hexagon a,hexagon b)
    {

    }

    public void PushLine(Vector3 basepos,Vector3 direction)
    {
        //链表方向和direcntion方向相同
        Vector3 StartPos = basepos;
        List<hexagon> Lines = new List<hexagon>();
        while (!IsTouchWall(StartPos))
        {
            StartPos += direction;
        }
        Lines.Add(FindHex(StartPos));
        StartPos -= direction;
        while (!IsTouchWall(StartPos))
        {
            Lines.Add(FindHex(StartPos));
            StartPos -= direction;
        }
        Lines.Add(FindHex(StartPos));
        //装载完毕，链表是推动前的状态且Lines不变
        PushAnim(Lines);//推动动画
        Vector3 LastPosition = Lines[Lines.Count - 1].transform.position;
        Vector3 LastPos = Lines[Lines.Count - 1].Pos;
        for(int i = 1; i < Lines.Count; i++)
        {
            Lines[i].transform.position = Lines[i - 1].transform.position;
            Lines[i].Pos = Lines[i - 1].Pos;
        }
        Lines[0].transform.position = LastPosition;
        Lines[0].Pos = LastPos;
    }

    public List<Vector3> GetLinePos(Vector3 basepos, Vector3 direction)//hexas[0], hexas[1]-hexas[0]
    {
        Vector3 StartPos = basepos;
        List<hexagon> Lines = new List<hexagon>();
        while (!IsTouchWall(StartPos))
        {
            StartPos += direction;
        }
        Lines.Add(FindHex(StartPos));
        StartPos -= direction;
        while (!IsTouchWall(StartPos))
        {
            Lines.Add(FindHex(StartPos));
            StartPos -= direction;
        }
        Lines.Add(FindHex(StartPos));
        List<Vector3> res = new List<Vector3>();
        foreach(hexagon hexagon1 in Lines)
        {
            res.Add(hexagon1.Pos);
        }
        return res;
    }


    private void PushAnim(List<hexagon>hexs)
    {

    }

    public bool IsTouchWall(Vector3 vector)
    {
        if(Mathf.Abs(vector.x)==2|| Mathf.Abs(vector.y) == 2|| Mathf.Abs(vector.z) == 2)
        {
            return true;
        }
        else
        {
           return false;
        }
    }

    public Vector3 GetNearestHexPos(Vector2 WorldVector)
    {
        float min = 99999f;
        Vector3 v = new Vector3(0, 0, 0);
        foreach(var i in cells)
        {
            if((WorldVector-(Vector2)i.transform.position).magnitude < min)
            {
                min = (WorldVector - (Vector2)i.transform.position).magnitude;
                
                v = i.Pos;
            }
        }

        if (min == 99999f&&cells.Count==19) Debug.Log("error");
        return v;

    }

    public hexagon GetHexagon(Vector3 pos)
    {
        foreach (hexagon hexa in cells) 
        {
            if (hexa.Pos == pos) 
            {
                return hexa;
            }
        }
        Debug.Log("找不到Hexa");
        return null;
    }





    public bool ExistPanel(Vector2 WorldVector)
    {
        float length = Data.Length;
        //Debug.Log("world:"+WorldVector );
        //Debug.Log("position:" + FindHex(GetNearestHexPos(WorldVector)));
        if (IsTouchWall(GetNearestHexPos(WorldVector))){
            
            Vector2 position=FindHex(GetNearestHexPos(WorldVector)).transform.position;
            
            if ((position - WorldVector).magnitude <= length)
            {
               
                return true;
            }
            else
            {
                return false;
            }

        }
        else
        {
            return true;
        }
    }

    public bool IsOK2Lay(CardObject cardObject,Vector3 pos)
    {
        foreach(hexagon hexagon1 in cardObject.hexagons)
        {
            Vector3 finalPos = hexagon1.Pos + pos;
            if (!ExistPanel(Data.Instance.getWorldPos(finalPos)))
            {
                return false;
            }
        }

        return true;
    }
    //任务：推行
       //动态加载变化长度->cardObject
       //display
    public void Change(CardObject cardObject,Vector3 CentrePos)
    {
        OperationThings= new List<Vector3>();
        List<Vector3> hexas = new List<Vector3>();
        foreach(hexagon hexa in cardObject.hexagons)//旋转时用的是
        {
            hexas.Add(hexa.Pos+CentrePos);
        }
        PresentOperation = cardObject.changeType;
        foreach(var i in hexas)
        {
            OperationThings.Add(i);
        }
        switch (cardObject.changeType)
        {
            case Data.ChangeType.RotationClock:
                TurnClock(hexas);
                break;
            case Data.ChangeType.RotationAntiClock:
                AntiTurnClock(hexas);
                break;
            case Data.ChangeType.ExChange:
                ExchangeTwoHex(hexas[0], hexas[1]);
                break;
            case Data.ChangeType.Push:
                PushLine(hexas[0], hexas[1]-hexas[0]);
                break;
        }
        //鼠标没上盘之前：2
        //鼠标上盘过后，根据长度：对应动态加载3,4,5
        //离开：2

        
    }

    Data.ChangeType PresentOperation;
    public List<Vector3> OperationThings = new List<Vector3>();

    public void DisPlay(CardObject cardObject,Vector3 CentrePos,bool TrulyPut)
    {
        if (OperationThings.Count != 0)
        {
            Revert(cardObject);
        }
        Change(cardObject,CentrePos);
        GameObject.Find("Map").GetComponent<LightCheck>().StartCheck(TrulyPut);
    }
    /*
     棋盘外->棋盘内：Display
     棋盘内->棋盘内: Display
     离开棋盘:Revert
      
         */
    public void Revert(CardObject cardObject)
    {
        switch (cardObject.changeType)
        {
            case Data.ChangeType.RotationClock:
                AntiTurnClock(OperationThings);
                break;
            case Data.ChangeType.RotationAntiClock:
                TurnClock(OperationThings);
                break;
            case Data.ChangeType.ExChange:
                ExchangeTwoHex(OperationThings[1], OperationThings[0]);
                break;
            case Data.ChangeType.Push:
                PushLine(OperationThings[0], OperationThings[0]-OperationThings[1]);
                break;
        }
        PresentOperation = default;
        OperationThings= new List<Vector3>();
    }







}
